﻿/*
 * protocolmasters.hpp
 *
 *  Created on: 2017年8月27日
 *      Author: work
 */

#ifndef _DM_OS_PROTOCOL_PROTOCOLMASTERS_HPP_
#define _DM_OS_PROTOCOL_PROTOCOLMASTERS_HPP_

#include <dm/export.hpp>

#ifndef DM_API_OS_PROTOCOL
#define DM_API_OS_PROTOCOL DM_API_IMPORT
#endif

#include <dm/os/protocol/protocolmasterbase.hpp>
#include <dm/scada/deviceagent.hpp>

namespace dm{
namespace os{
namespace protocol{

/**
 * 一对多主站类
 * 用于采集多个子站设备
 */
class DM_API_OS_PROTOCOL CProtocolMasters:public CProtocolMasterBase{
public:
	CProtocolMasters();
	virtual ~CProtocolMasters();

	/**
	 * 设置支持的设备数量
	 * @param cnt
	 */
	void setDeviceCount( const int& cnt );

	/**
	 * 设置设备名
	 * 需要先设置好设备数量后，调用本函数。
	 * @param name 设备名
	 * @param idx 设备编号
	 * @return 是否成功
	 */
	bool setDevice( const char* name,const int& idx );

	bool setDevice( const char* name,const int& idx,const dm::scada::CDeviceAgent::SSignalsSize& size );

	/**
	 * 设置设备ID
	 * @param id 设备ID
	 * @param idx 设备编号
	 * @return
	 */
	bool setDevice( const int& id,const int& idx );

	bool setDevice( const int& id,const int& idx,const dm::scada::CDeviceAgent::SSignalsSize& size );

	/**
	 * 获取设备数量
	 * @return
	 */
	inline const int& getDevcieCount()const{
		return m_devCnt;
	}

	/**
	 * 获取设备代理器
	 * @param idx 设备索引
	 * @return
	 */
	dm::scada::CDeviceAgent* getDeviceAgent( int idx );

	/**
	 * 获取设备代理器
	 * @param idx 设备索引
	 * @return
	 */
	const dm::scada::CDeviceAgent* getDeviceAgent( int idx )const;

	/**
	 * 设置当前被激活的设备
	 * @param index
	 */
	virtual void setCurDev( int index );

	/**
	 * 获取当前被激活的设备
	 * @return
	 */
	inline const int& getCurDev()const{
		return m_curDev;
	}

	inline dm::scada::CDeviceAgent* curDeviceAgent(){
		return getDeviceAgent(m_curDev);
	}

	inline const dm::scada::CDeviceAgent* curDeviceAgent()const{
		return getDeviceAgent(m_curDev);
	}

	/**
	 * 远控是否属于本地设备
	 * @param idx
	 * @return
	 */
	bool isLocalRemoteCtl( const dm::msg::index_t& idx )const;

	/**
	 * 参数是否属于本地设备
	 * @param idx
	 * @return
	 */
	bool isLocalPara( const dm::msg::index_t& idx )const;

	/**
	 * 根据远控获取设备索引号
	 * @param idx
	 * @return
	 */
	int getDevIndexByRemoteCtl( const dm::msg::index_t& idx )const;

	/**
	 * 根据参数获取设备索引号
	 * @param idx
	 * @return
	 */
	int getDevIndexByPara( const dm::msg::index_t& idx )const;

	/**
	 * 链路连接处理
	 * 默认会更新所有设备的状态
	 * @param now
	 */
	virtual void onLinkSettled( const ts_t& ts,const rts_t& rts );

	/**
	 * 链路连接断开处理
	 * 默认会更新所有设备的状态
	 * @param now
	 */
	virtual void onLinkClosed( const ts_t& ts,const rts_t& rts );

	/**
	 * 更新设备接收数据时刻
	 * 如果设置了当前设备，只会更新当前设备的接收数据。
	 * 否则会更新所有设备的接收数据
	 * @param bytes
	 * @param n
	 */
	virtual void updateRecvTime( dm::uint32 bytes,const rts_t& rts );

	/**
	 * 更新设备的发送数据时刻
	 * 如果设置了当前设备，只会更新当前设备的发送数据
	 * 否则会更新所有设备的接收数据
	 * @param bytes
	 * @param n
	 */
	virtual void updateSendTime( dm::uint32 bytes,const rts_t& rts );

private:
	/**
	 * 设备数
	 */
	int m_devCnt;

	// 子设备管理器
	dm::scada::CDeviceAgent* m_devAgents;

	int m_curDev;	// 当前被激活的设备：-1表示无设备激活
};

}
}
}

#endif /* DM_RUNTIME_INCLUDE_DM_OS_PROTOCOL_PROTOCOLMASTERS_HPP_ */
